/**
 * 询价.COM v1.0.0
 * http://xun-jia.com/
 *
 * Copyright (c) 2009 
 * 四川漾天空网络科技有限公司
 * 成都市天府软件园A3栋2楼
 *
 */
package com.xunjia.util;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.StringTokenizer;

import javax.mail.Authenticator;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.NoSuchProviderException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.Message.RecipientType;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

import org.apache.log4j.Logger;

/**
 * 
 * 郵件發送類
 * 
 * @author Mark
 * 
 * @Email Mark_yang@xun-jia.com
 * 
 * @Date 2009-4-3 下午12:09:16
 * 
 */
public class MailUtil implements Serializable {
	// 日誌處理對象
	private static final Logger logger = Logger.getLogger(MailUtil.class);
	// 序列號
	private static final long serialVersionUID = -4189996117899933551L;
	// 郵件配置文件名稱
	private static final String MAIL = "mail";
	// 郵件發送地址(用戶名)
	private static final String USER = "mail.user";
	// 郵件發送密碼
	private static final String PASSWORD = "mail.password";
	// 郵件傳送協議類型
	private static final String PROTOCAL = "mail.transport.protocol";
	// 字符串分隔符
	private static final String SEPARATOR = ";";
	// javaMail配置文件
	private ResourceBundle setup;
	// 郵件會話
	private Session mailSession;
	// 郵件傳送協議
	private String protocal;
	// 發送郵件對象
	private Transport sendMail;
	// 主題
	private String subject;
	// 內容
	private String content;
	// 附件
	private List<File> attachFile;
	// 發送郵件地址
	private String from;
	// 接收郵件地址
	private String to;
	// 抄送郵件地址
	private String cc;
	// 再抄送郵件地址
	private String bcc;

	/**
	 * 構造函數
	 * 
	 * @param to
	 *            接收郵件地址,多個郵件地址,用';'隔開
	 * @param cc
	 *            抄送郵件地下
	 * @param bcc
	 *            二次抄送郵件地址
	 * @param subject
	 *            郵件主題
	 * @param content
	 *            郵件內容
	 * @param attachFiles
	 *            附件,多個附件,用';'隔開
	 * @throws NoSuchProviderException
	 */
	public MailUtil(String to, String cc, String bcc, String subject,
			String content, List<File> attachFiles) {
		// 接收郵件地址
		this.to = to;
		// 郵件主題
		this.subject = subject;
		// 郵件內容
		this.content = content;
		// 附件
		this.attachFile = attachFiles;
		// 抄送郵件地下
		this.cc = cc;
		// 二次抄送郵件地址
		this.bcc = bcc;
	}

	/**
	 * 準備郵件發送對象
	 * 
	 * @throws NoSuchProviderException
	 */
	public void prepareMailer() {
		try {
			// javaMail配置對象
			Properties props = new Properties();
			// 獲取javaMail配置文件
			setup = ResourceBundle.getBundle(MAIL);
			// 獲取配置屬性KEY
			Enumeration<String> keys = setup.getKeys();
			// 當存在KEY時
			while (keys.hasMoreElements()) {
				// 獲取當前KEY
				String key = keys.nextElement();
				// 如果讀到用戶名時,退出
				if (key.equals(USER) || key.equals(PASSWORD)) {
					continue;
				}
				// 將當前KEY與值存入配置對象
				props.put(key, setup.getString(key));
			}
			// 獲取郵件會話
			mailSession = Session.getInstance(props, new Authenticate(setup
					.getString(USER), setup.getString(PASSWORD)));
			// 是否顯示測試消息
			mailSession.setDebug(true);
			// 發送郵件地址
			this.from = setup.getString(USER);
			// 郵件傳送協議
			this.protocal = setup.getString(PROTOCAL);
			// 發送郵件對象
			this.sendMail = mailSession.getTransport(protocal);
		} catch (NoSuchProviderException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 發送HTML郵件
	 * 
	 * @param contentType
	 *            郵件內容編碼格式
	 * @return
	 */
	public boolean sendHTMLMail() {
		try {
			// 新建郵件消息
			MimeMessage message = new MimeMessage(mailSession);
			// 設置發件人地址
			message.setFrom(new InternetAddress(this.from));
			// 設置接收人地址
			StringTokenizer token = new StringTokenizer(this.to, SEPARATOR);
			// 設置接收人
			while (token.hasMoreTokens()) {
				message.addRecipients(RecipientType.TO, token.nextToken());
			}
			// 設置抄送人
			if (!StringUtil.isEmpty(cc)) {
				message.addRecipients(RecipientType.CC, cc);
			}
			// 設置二次抄送人
			if (!StringUtil.isEmpty(bcc)) {
				message.addRecipients(RecipientType.BCC, bcc);
			}
			// 設置主題
			message.setSubject(subject);
			// 新建郵件內容
			Multipart content = new MimeMultipart();
			// 添加郵件主體
			addMessageBodyPart(content);
			// 添加附件主體
			addFileBodyPart(content);
			// 設置郵件內容
			message.setContent(content, "text/html");
			// 保存消息
			message.saveChanges();
			message.setHeader("X-Mailer", subject);
			// 發送郵件服務器
			String host = setup.getString("mail." + protocal + ".host");
			// 連接到服務器
			sendMail.connect(host, setup.getString(USER), setup
					.getString(PASSWORD));
			// 設置發送郵件時間
			message.setSentDate(new Date());
			// 發送消息
			sendMail.sendMessage(message, message.getAllRecipients());
		} catch (AddressException e) {
			logger.debug(e.getMessage());
			return false;
		} catch (MessagingException e) {
			logger.debug(e.getMessage());
			return false;
		} catch (IOException e) {
			logger.debug(e.getMessage());
			return false;
		}
		return true;
	}

	/**
	 * 添加郵件消息主體
	 * 
	 * @param content
	 *            郵件
	 * @param contentType
	 *            消息編碼類型
	 * @throws MessagingException
	 */
	private void addMessageBodyPart(Multipart content)
			throws MessagingException {
		// 新建郵件體
		MimeBodyPart contentBody = new MimeBodyPart();
		// 設置郵件主體
		contentBody.setText(this.content, null, "html");
		// 添加郵件主體
		content.addBodyPart(contentBody);
	}

	/**
	 * 添加附件主體
	 * 
	 * @param content
	 *            郵件
	 * @param contentType
	 *            編碼類型
	 * @throws MessagingException
	 * @throws IOException
	 */
	private void addFileBodyPart(Multipart content) throws MessagingException,
			IOException {
		// 設置郵件主體
		for (File files : this.attachFile) {
			// 新建郵件體
			MimeBodyPart fileBody = new MimeBodyPart();
			// 設置當前文件數據處理器
			fileBody.attachFile(files);
			// 設置文件名稱
			fileBody.setFileName(files.getName());
			// 添加郵件附件主體
			content.addBodyPart(fileBody);
		}
	}

	/**
	 * 郵件登陸認證器
	 * 
	 * @author Mark
	 * 
	 * @Email Mark_yang@xun-jia.com
	 * 
	 * @Date 2009-4-3 下午01:52:02
	 * 
	 */
	private class Authenticate extends Authenticator {
		// 用戶名
		private String username;
		// 密碼
		private String password;

		/**
		 * 構造函數
		 * 
		 * @param username
		 *            用戶名
		 * @param password
		 *            密碼
		 */
		public Authenticate(String username, String password) {
			// 設置用戶名
			this.username = username;
			// 設置密碼
			this.password = password;
		}

		/**
		 * 返回密碼驗證器
		 * 
		 * @return
		 */
		public PasswordAuthentication getPasswordAuthentication() {
			return new PasswordAuthentication(username, password);
		}
	}
}
